package com.atguigu.tingshu.common.login;


import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.constant.PublicConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import org.apache.tomcat.util.http.fileupload.RequestContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class LoginAspect {
    @Autowired
    StringRedisTemplate stringRedisTemplate;


        @Around(value = "@annotation(com.atguigu.tingshu.common.login.Login)")
        public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {

            try {
                MethodSignature signature =(MethodSignature) pjp.getSignature();
                Method method = signature.getMethod();
                Login annotation = method.getAnnotation(Login.class);
                boolean login = annotation.isLogin();
                if (login == false){
                    return pjp.proceed();
                }

                ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                String token = requestAttributes.getRequest().getHeader("token");
                //使用公钥解锁
                Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(PublicConstant.PUBLIC_KEY));
                //获取载荷
                String claims = jwt.getClaims();
                Map<String,String> map = JSONObject.parseObject(claims, Map.class);
                String id =  map.get("id");
                String redisToken = stringRedisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + id);
                if (StringUtils.isEmpty(redisToken) || !token.equals(redisToken)){
                    throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
                }
                //判断是不是过期了
                String time = map.get("time");
                if (System.currentTimeMillis()-Long.parseLong(time)>=0){
                    stringRedisTemplate.expire(RedisConstant.USER_LOGIN_KEY_PREFIX + id,1, TimeUnit.DAYS);
                }
                AuthContextHolder.setUserId(Long.parseLong(id));


                // start stopwatch
                Object retVal = pjp.proceed();
                // stop stopwatch
                return retVal;
            } finally {
              AuthContextHolder.removeUserId();
            }
        }


}
